/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package systole.view;

import java.util.Iterator;
import java.util.Vector;
import javax.swing.JOptionPane;
import systole.domain.analysis.Analysis;
import systole.exceptions.ExceptionDAO;
import systole.persistence.FacadeDB;
import systole.persistence.SessionManager;
import systole.synchronization.SyncController;
import systole.view.analysis.ControllerAnalysisView;
import systole.view.averages.ControllerAverageView;
import systole.view.crud.comment.ControllerCommentView;
import systole.view.crud.comparatives.ControllerComparativeView;
import systole.view.crud.conclusion.ControllerConclusionView;
import systole.view.crud.family.ControllerFamilyView;
import systole.view.crud.medic.ControllerMedicView;
import systole.view.crud.medicine.ControllerMedicineView;
import systole.view.crud.pathology.ControllerPathologyView;
import systole.view.crud.patient.ControllerPatientView;
import systole.view.crud.profession.ControllerProfessionView;
import systole.view.crud.signalFrequency.ControllerSignalFrequencyView;
import systole.view.crud.sport.ControllerSportView;
import systole.view.crud.surgery.ControllerSurgeryView;
import systole.view.messages.DialogsMessages;
import systole.view.preview.PreviewController;
import systole.view.settings.ControllerSettings;
import systole.view.settings.report.ControllerReportSettings;
import systole.view.settings.standardValues.ControllerStandardValues;
import systole.view.tabs.JpnlAnalysis;
import systole.view.tabs.controllers.AnalysisController;
import systole.view.utils.ErrorDialog;

/**
 *
 * @author jmj
 */
public class MainController {

    private SystoleView mainForm;
    private Vector<AnalysisController> analysisList;

    /**
     * @param mainForm
     */
    public MainController(SystoleView mainForm) {
        this.mainForm = mainForm;
        SessionManager.getInstance();
        FacadeDB.getInstance();
        this.analysisList = new Vector<AnalysisController>();
    }

    /**
     * 
     */
    public void adminPatients() {
        try {
            ControllerPatientView controllerPatientView = new ControllerPatientView();
            controllerPatientView.showForm(this.mainForm.getFrame());
            controllerPatientView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminMedics() {
        try {
            ControllerMedicView controllerMedicView = new ControllerMedicView();
            controllerMedicView.showForm(this.mainForm.getFrame());
            controllerMedicView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminSurgeries() {
        try {
            ControllerSurgeryView controllerSurgeryView = new ControllerSurgeryView();
            controllerSurgeryView.showForm(this.mainForm.getFrame());
            controllerSurgeryView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminSports() {
        try {
            ControllerSportView controllerSportView = new ControllerSportView();
            controllerSportView.showForm(this.mainForm.getFrame());
            controllerSportView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminMedicines() {
        try {
            ControllerMedicineView controllerMedicineView = new ControllerMedicineView();
            controllerMedicineView.showForm(this.mainForm.getFrame());
            controllerMedicineView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminPathologies() {
        try {
            ControllerPathologyView controllerPathologyView = new ControllerPathologyView();
            controllerPathologyView.showForm(this.mainForm.getFrame());
            controllerPathologyView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminSamplingPeriod() {
        try {
            ControllerSignalFrequencyView controllerSignalFrequencyView = new ControllerSignalFrequencyView();
            controllerSignalFrequencyView.showForm(this.mainForm.getFrame());
            controllerSignalFrequencyView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminComments() {
        try {
            ControllerCommentView controllerCommentView = new ControllerCommentView();
            controllerCommentView.showForm(this.mainForm.getFrame());
            controllerCommentView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminConclusions() {
        try {
            ControllerConclusionView controllerConclusionView = new ControllerConclusionView();
            controllerConclusionView.showForm(this.mainForm.getFrame());
            controllerConclusionView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminFamily() {
        try {
            ControllerFamilyView controllerFamilyView = new ControllerFamilyView();
            controllerFamilyView.showForm(this.mainForm.getFrame());
            controllerFamilyView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     *
     */
    public void adminProfessions() {
        try {
            ControllerProfessionView controllerProfessionView = new ControllerProfessionView();
            controllerProfessionView.showForm(this.mainForm.getFrame());
            controllerProfessionView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void adminComparatives() {
        try {
            ControllerComparativeView controllerComparativeView = new ControllerComparativeView();
            controllerComparativeView.showForm(this.mainForm.getFrame());
            controllerComparativeView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * 
     */
    public void newAnalysis() {
        AnalysisController anControl = new AnalysisController(this);
        if (anControl.createAnalysis()) {
            this.analysisList.add(anControl);
            this.mainForm.addAnalysisPanel(anControl.getFrmAnalysis());
        }
    }

    /**
     * 
     */
    public void openAnalysis() {
        try {
            ControllerAnalysisView controllerAnalysisView = new ControllerAnalysisView(this);
            controllerAnalysisView.showForm(this.mainForm.getFrame());
            controllerAnalysisView = null;
        } catch (ExceptionDAO ex) {
            FacadeDB.getInstance().refreshSession();
            ErrorDialog.showError(this.mainForm.getFrame(), ex.getMessage());
        }
    }

    /**
     * @param analysis
     */
    public void openAnalysis(Analysis analysis) {
        AnalysisController anControl = new AnalysisController(this);
        this.analysisList.add(anControl);
        anControl.openAnalysis(analysis);
        this.mainForm.addAnalysisPanel(anControl.getFrmAnalysis());
    }

    /**
     * 
     */
    public void saveAnalysis() {
        JpnlAnalysis analysis = (JpnlAnalysis) this.mainForm.getjTabPnlMain().getSelectedComponent();
        if (analysis != null) {
            if (analysis.getController().wasModified()) {
                analysis.getController().saveAnalysis(false);
            }
        }
    }

    /**
     * 
     */
    public void saveAllAnalysis() {
        for (int i = 0; i < this.analysisList.size(); i++) {
            this.analysisList.get(i).saveAnalysis(false);
        }
    }

    /**
     * @param jpnlAnalysis Tab to closeForm
     * 
     */
    public void closeAnalysis(JpnlAnalysis jpnlAnalysis) {

        if (jpnlAnalysis.getController().wasModified()) {
            int res = JOptionPane.showOptionDialog(this.mainForm.getFrame(),
                    DialogsMessages.SAVE_CHANGES, DialogsMessages.DIALOG_BOX_TITLE,
                    JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                    null, null);
            if (res == JOptionPane.CANCEL_OPTION) {
                return;
            }
            if (res == JOptionPane.YES_OPTION) {
                jpnlAnalysis.getController().saveAnalysis(true);
                return;
            }
        }

        int closeTabNumber = this.mainForm.getjTabPnlMain().indexOfComponent(jpnlAnalysis);
        this.mainForm.getjTabPnlMain().removeTabAt(closeTabNumber);
        this.analysisList.remove(jpnlAnalysis.getController());
        if (analysisList.isEmpty()) {
            FacadeDB.getInstance().refreshSession();
        }
        jpnlAnalysis.getController().clearObjectInstances();
    }

    protected boolean closeAnalysisOnExit(AnalysisController analysisController) {
        if (analysisController.wasModified()) {
            int res = JOptionPane.showOptionDialog(this.mainForm.getFrame(),
                    DialogsMessages.SAVE_CHANGES, DialogsMessages.DIALOG_BOX_TITLE,
                    JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                    null, null);

            if (res == JOptionPane.CANCEL_OPTION) {
                return false;
            }
            if (res == JOptionPane.YES_OPTION) {
                analysisController.saveAnalysis(true);
            }
        }
        return true;
    }

    /**
     * Close an analysis tab after process analysis
     * 
     * @param jpnlAnalysis
     */
    public void closeAnalysisAfterProcess(JpnlAnalysis jpnlAnalysis) {
        int closeTabNumber = this.mainForm.getjTabPnlMain().indexOfComponent(jpnlAnalysis);
        this.mainForm.getjTabPnlMain().removeTabAt(closeTabNumber);
        this.analysisList.remove(jpnlAnalysis.getController());
        if (analysisList.isEmpty()) {
            FacadeDB.getInstance().refreshSession();
        }
        jpnlAnalysis.getController().clearObjectInstances();
        System.gc();
    }

    /**
     * 
     */
    public void closeAllAnalysis() {
        Iterator<AnalysisController> itClose = this.analysisList.iterator();
        while (itClose.hasNext()) {
            AnalysisController currentController = itClose.next();
            this.mainForm.getjTabPnlMain().setSelectedComponent(currentController.getFrmAnalysis());
            if (this.closeAnalysisOnExit(currentController)) {
                int closeTabNumber = this.mainForm.getjTabPnlMain().indexOfComponent(currentController.getFrmAnalysis());
                this.mainForm.getjTabPnlMain().removeTabAt(closeTabNumber);
            }
        }
    }

    /**
     * 
     */
    public void showAverages() {
        ControllerAverageView controllerAverageView = new ControllerAverageView();
        controllerAverageView.showForm(this.mainForm.getFrame());
        controllerAverageView = null;
    }

    /**
     * 
     */
    public void reportSettings() {
        ControllerReportSettings controllerReportSettings = new ControllerReportSettings(this.mainForm.getFrame());
        controllerReportSettings.showSettings();
        controllerReportSettings = null;
    }

    /**
     * 
     */
    public void settings() {
        ControllerSettings controllerSettings = new ControllerSettings(this.mainForm.getFrame());
        controllerSettings.showSettings();
        controllerSettings = null;
    }

    /**
     * 
     */
    public void preview() {
        PreviewController previewController = new PreviewController();
        previewController.showForm(this.mainForm.getFrame());
        if (previewController.hasttoInitNewanalysis()) {
            AnalysisController anControl = new AnalysisController(this);
            if (anControl.createAnalysis(previewController.getRawSignal(), previewController.getFilePath())) {
                this.analysisList.add(anControl);
                this.mainForm.addAnalysisPanel(anControl.getFrmAnalysis());
            }
        }
        previewController = null;
    }

    /**
     * close the application
     * 
     * @return if the application will be closed
     */
    public boolean closeApplication() {
        if (this.analysisList.isEmpty()) {
            return (JOptionPane.OK_OPTION == JOptionPane.showOptionDialog(SystoleApp.getApplication().getMainFrame(),
                    DialogsMessages.CLOSE_APPLICATION, DialogsMessages.DIALOG_BOX_TITLE,
                    JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                    null, null));
        }
        Iterator<AnalysisController> itClose = this.analysisList.iterator();
        Vector<AnalysisController> toRemove = new Vector<AnalysisController>();
        while (itClose.hasNext()) {
            AnalysisController currentController = itClose.next();
            this.mainForm.getjTabPnlMain().setSelectedComponent(currentController.getFrmAnalysis());
            if (!this.closeAnalysisOnExit(currentController)) {
                this.analysisList.removeAll(toRemove);
                return false;
            }
            int closeTabNumber = this.mainForm.getjTabPnlMain().indexOfComponent(currentController.getFrmAnalysis());
            if (closeTabNumber != -1) {
                this.mainForm.getjTabPnlMain().removeTabAt(closeTabNumber);
                toRemove.add(currentController);
            }
        }
        this.analysisList.removeAll(toRemove);
        return true;
    }

    /**
     * print report of selected analysis
     */
    public void printReport() {
        JpnlAnalysis analysis = (JpnlAnalysis) this.mainForm.getjTabPnlMain().getSelectedComponent();
        if (analysis != null) {
            analysis.getController().printReport();
        }
    }

    /**
     * preview report of selected analysis
     */
    public void previewReport() {
        JpnlAnalysis analysis = (JpnlAnalysis) this.mainForm.getjTabPnlMain().getSelectedComponent();
        if (analysis != null) {
            analysis.getController().previewReport();
        }
    }

    /**
     * export report of selected analysis
     */
    public void exportReport() {
        JpnlAnalysis analysis = (JpnlAnalysis) this.mainForm.getjTabPnlMain().getSelectedComponent();
        if (analysis != null) {
            analysis.getController().generateReport();
        }
    }

    /**
     * adimin standard values
     */
    public void adminStandardValues() {
        ControllerStandardValues controllerStandardValues = new ControllerStandardValues();
        controllerStandardValues.showForm(this.mainForm.getFrame());
        controllerStandardValues = null;
    }

    public void syncInfo() {
        if (!this.analysisList.isEmpty()) {
            ErrorDialog.showError(this.mainForm.getFrame(), "Debe cerrar todos los analisis");
            return;
        }
        SyncController syncController = new SyncController();
        syncController.runSynchronization();
    }
}
